package com.apobates.jforum.grief.aurl.executor;

import java.util.Optional;
import java.util.function.Function;

/**
 * HClientExecutor的响应内容
 * @param code http状态码
 * @param body http响应正文
 * @param message 执行消息
 * @param <T> 响应正文的类型
 */
public record HClientResponse<T>(int code, Optional<T> body, String message) {
    /**
     * 创建实例
     * @param code 状态码
     * @param body 消息/响应内容
     * @return
     * @param <T>
     */
    public static <T> HClientResponse<T> success(int code, T body){
        return new HClientResponse<>(code, Optional.ofNullable(body), "OK");
    }

    /**
     * 非法请求(400)
     * @param message 消息
     * @return
     */
    public static HClientResponse<String> badRequest(String message){
        return new HClientResponse<>(400, Optional.empty(), message);
    }

    /**
     * 无法访问
     * @param message 消息
     * @return
     */
    public static HClientResponse<String> notFound(String message){
        return new HClientResponse<>(404, Optional.empty(), message);
    }

    /**
     * 服务器错误
     * @param message 消息
     * @return
     */
    public static <T> HClientResponse<T> serverError(String message){
        return new HClientResponse<>(500, Optional.empty(), message);
    }

    /**
     * 返回StatusCode的枚举
     * @return
     */
    public StatusCode statusCode(){
        return StatusCode.getInstance(this.code());
    }

    /**
     * 将响应内容转换为指定的类型
     * @param converter 转换器
     * @param defaultIns 若响应内容不可用时的默认值
     * @return
     * @param <R> 转换后的类型
     */
    public <R> R convert(Function<T,R> converter, R defaultIns){
        return body().map(converter).orElse(defaultIns);
    }

    // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#information_responses
    public enum StatusCode{
        Undefined, ServerError, ClientError, Redirection, Success, Information;

        private static StatusCode getInstance(int statuscode){
            if(statuscode >= 100 && statuscode <= 199){
                // 100 – 199
                return Information;
            }
            if(statuscode >= 200 && statuscode <= 299){
                // 200 – 299
                return Success;
            }
            if(statuscode >= 300 && statuscode <= 399){
                // 300 – 399
                return Redirection;
            }
            if(statuscode >= 400 && statuscode <= 499){
                // 400 – 499
                return ClientError;
            }
            if(statuscode >= 500 && statuscode <= 599){
                // 500 – 599
                return ServerError;
            }
            return Undefined;
        }

        /**
         * 是否成功
         * @return true是/false不是
         */
        public boolean isSuccess(){
            return this == StatusCode.Success;
        }

        /**
         * 是否是服务器错误
         * @return true是/false不是
         */
        public boolean isServerError(){
            return this == StatusCode.ServerError;
        }

        /**
         * 是否是客户端错误
         * @return true是/false不是
         */
        public boolean isClientError(){
            return this == StatusCode.ServerError;
        }
    }
}
